2) put the name you want the user to see in line 1
3) put these scripts into the fields scripts
4) type "menuitems" into line 3
5) resize the field so only the first line is showing
6) set the locktext of the field to true
Note: If you use a script where the user level has been set so that the menu option for "new field" is not available you should insert the set user level commands at the places marked in the scripts. This is necessary only for the HyperCard™ only version.
--FUNCTIONS & HANDLERS FROM THE ROOT CLASS OBJECTS
on executeinstancelistmenu hit,list
--input number of item selected from instance list,instance list
--This lets the user change the value of instance variables
put word 3 to (the number of words in item hit of list) of list into¬
temp
ask "Enter value for " & temp with line hit +2 of me
if it is not empty then
put it into line hit+2 of me
end if
end executeinstancelistmenu
on executemethodmenu hit,list
--input number of item selected from method list,method list
--this just sends the selected message to the instances
send (item hit of list) to me
end executemethodmenu
function instancelistmenu
--output the instance list
put getinstancelist (line 2 of me) into temp
put the number of items in temp into numinstancevars
put empty into list
repeat with x=1 to numinstancevars
put "Set the " & item 1 of item x of temp into item x of list
end repeat
put ",Cancel" after list
return list
end instancelistmenu
function methodlistmenu
--output the method list
put getinstancehandlernames(the short name of me) into temp
repeat with i=2 to the number of lines in temp
put line i of temp into item i-1 of list
end repeat
put ",Cancel" after list
return list
end methodlistmenu
function popmenu list,loc
-- input: list of options,location of menu
-- output: number of menu item picked 0 if none or cancel
-- this takes a list of options,and a menu location and displays
-- a menu. It also checks to see if the user picks the cancel option
if the number of items in list < 1 then
put "Cancel" into list
end if
put ((the number of items in list) + 10) into nlist
put redolist (list) into list
put item 1 of loc+50 into h
put item 2 of loc+50 into v
--This is Andrew Gilmartin's XFCN
get PopUpMenu(list,nlist, v, h)
--This is message to let the user know that he has to hold the mouse
--down on the field until the menu appears
if it is 0 then
put "You must hold the mouse button down on this button to see the menu"
end if
return it
end popmenu
function redolist list
--input list in format "a,b,c,d"
--output list in format "a;b;c;d"
-- this just reformats the list for popupmenu to use ";" as the
-- item separator not ","
put empty into newlist
repeat with x=1 to the number of items in list
put item x of list & ";" after newlist
end repeat
return newlist
end redolist
on deleteme
-- this allows an object to be deleted
if the userlevel is not 5 then
put the userlevel into temp1
set the userlevel to 5
else
put empty into temp1
end if
select me
domenu "cut field"
if temp1 is not empty then
set the userlevel to 5
end if
choose browse tool
end deleteme
on removecomments
--NOTE: This is a generally useful script not specifically required for the pop-up --menu functionality. This removes all comments from a script.
set the cursor to watch
put the script of me into temp
repeat with i=1 to the number of lines in temp
if line i of temp is not empty then
put " " into ctemp
put 0 into j
repeat until ctemp is not " "
add 1 to j
put char j of line i of temp into ctemp
end repeat
if ctemp is "-" then
put empty into line i of temp
end if
end if
end repeat
put removeemptylines (temp) into temp
set the script of me to temp
end removecomments
function getinstanceval instancevarname,classname
--input: instance variable name,name of class
--output: value for the instance variable of the target
-- this function gets the value of any instance variable for an
-- object. This is better than using line numbers because you
-- don't have to change any scripts if you change the number or order
-- of instance variables in a class
put getinstancelist (classname,0) into temp
put findinstancenum (instancevarname,temp) into tempnum
put the short name of the target into fieldname
put line (tempnum+2) of card field fieldname into value
return value
end getinstanceval
on setinstanceval instancevarname,classname,value
--input: instance variable name,name of class,value
--output: set the instance variable of the target to value
-- this function sets the value of any instance variable for an
-- object. This is better than using line numbers because you
-- don't have to change any scripts if you change the number or order
-- of instance variables in a class
put getinstancelist(classname,0) into temp
put findinstancenum(instancevarname,temp) into tempnum
put the short name of the target into fieldname
put value into line (tempnum+2) of card field fieldname
end setinstanceval
function findinstancenum instancevarname,list
--input: instance variable name,list of instance variables in class
--output: sequence number of this instance variable in the list
--error: returns -1 if name not found
-- given an instance variable name it and a list of instance names
-- this returns the item number of the instance name
put -1 into hit
repeat with x=1 to the number of items in list
if item x of list is instancevarname then
return x
put 0 into hit
exit repeat
end if
end repeat
if hit < 0 then
put "Error:findinstacenum: Instance Name not found"
end if
return -1
end findinstancenum
function class objectname
-- this returns the class of an object
put objectname
wait 2 seconds
return line 2 of card field (objectname)
end class
function classnumber classname
-- this returns the item number of the argument in the class list
global classnames
put -1 into classnum
repeat with i=1 to the number of items in classnames
if classname is item i of classnames then
put i into classnum
exit repeat
end if
end repeat
return classnum
end classnumber
function getinstancehandlernames iname
--input instance name
--output list of all of the message handlers in the script
put the script of card field iname into temp
put scanhandlers(temp) into methodlist
return methodlist
end getinstancehandlernames
function scanhandlers temp
--input script
--output list with the names of the message handlers (1/line)
put 0 into nummethods
put empty into methodlist
repeat with i=1 to number of lines in temp
if word 1 of line i of temp is "on" then
add 1 to nummethods
put word 2 of line i of temp into line nummethods of methodlist
end if
end repeat
return methodlist
end scanhandlers
These are the handlers and functions necessary to eliminate the need for the XFCN. Just replace the handlers with the same name in the above listing by these and add those that don't appear in the above listing and the field will work as a pop-up menu.
on mouseup
--this is here to override the subsequent mouseup handler which will
-- be placed in the field containing the popup menu. If this weren't here
-- then everytime you click the mouse on the original field the mouseup
-- handler for the menu field would be activated.
end mouseup
on mouseup
--this script is placed in the menu field to handle the users selection
-- the name of the chosen item is returned (to avoid the handler in
-- the original field (itempicked) from having to know what the
-- possible choices were. The cmdflag(which notes whether you're
-- working with menu choices,instance variable setting,or firing
-- handlers) is also returned.
-- The name of the original field is contained in the second to
-- last line in the menu,while the cmdflag value is contained in the
-- last line. Both of which are kept invisible by the selected
-- sizing for the menu field
put the clickloc into loc
put linechoosenfixed (loc) into itemchosen
put line itemchosen of me into itemchosen
put last line of me into cmdflag
put number of lines in me -1 into temp
put line temp of me into dest
send "itempicked itemchosen,cmdflag" to dest
-- now that we're done with it let's delete the menu field
-- NOTE: If you want the menu to hang around just eliminate the next
-- three lines and included a menu option to eliminate the menu.
--if the userlevel is not 5 then <========== To insure menu options available
-- put the userlevel into temp1 <========== To insure menu options available
-- set the userlevel to 5 <========== To insure menu options available
-- else <========== To insure menu options available
-- put empty into temp1 <========== To insure menu options available
-- end if <========== To insure menu options available
select me
domenu "cut field"
-- if temp1 is not empty <========== To insure menu options available
-- set the userlevel to temp1 <========== To insure menu options available
-- end if <========== To insure menu options available
choose browse tool
--set the userlevel to temp1 <========== To insure menu options available
end mouseup
function linechoosenfixed loc
--input x,y location of the mouse click(use the clickloc)
-- This is a generally useful function which takes the clickloc as
-- input and finds out which line in a field was clicked on
put second item of loc into pos
put pos - the top of the target into pos
get the textheight of the target
put it into size
put trunc(pos/size)+1 into linehit
return linehit
end linechoosenfixed
on mousedown
--OVERRIDE:POPUP MENU: This is the mousedown handler for the popup
--menu HC only class. Holding the mouse down on gives the user defined
--pop-up menu. Holding the mouse and option key down gives a menu to
--change the values of the instance variables. Holding the mouse and
--shift key down give a menu of the messages (methods) that the
--instance can handle.
put 0 into cmdflag
set the cursor to watch
-- handle the user setting the value of the instance variables
if the optionkey is down then
put 1 into cmdflag
put instancelistmenu() into list
-- handlethe user firing the handlers
else if the shiftkey is down then
put 2 into cmdflag
put methodlistmenu() into list
-- handle the user using the pop-up menu
else
put getinstanceval(menuitems,line 2 of me) into list
end if
put the clickloc into loc
-- build and display the pop-up menu
popHCmenu list,loc,cmdflag
end mousedown
on itempicked itemchosen,cmdflag
--input name of the menu item selected,the command flag
-- since the HC version is modeless the handler has to be broken into
-- two pieces,one to make the menu field and one to handle the message
-- that the user has picked an item.
set the cursor to watch
if itemchosen is not "empty" and itemchosen is not "cancel" then
-- This section actually implements the menu action. Note that
-- we're using the handlemenu and executemenu handlers a little
-- differently than they were designed for. They were designed to
-- make a selection from a list but by sending them a 1 item list
-- we avoid having to make the list a global variable,or regenerate
-- it which could be very slow,and we also avoid writing 3 new
-- handlers for this class
if cmdflag = 0 then
handlemenu 1,itemchosen
else if cmdflag= 1 then
executeinstancelistmenu 1,itemchosen
else if cmdflag=2 then
executemethodmenu 1,itemchosen
end if
end if
end itempicked
on popHCmenu list,loc,cmdflag
--input list of menu options,location of menu,command flag
-- This handler sets up the menu
--first convert the list into a variable with each item in 1 line
put listtoline(list) into list
put the number of lines in list into temp
--compute the height and width of the field
-- Note if you change the font size in the makefield handler you
-- need to change the width and height computations
put (temp*9)+3 into height
put the target into line temp+1 of list
put cmdflag into line temp+2 of list
put 0 into maxchar
repeat with i=1 to temp
if the number of chars in line i of list > maxchar then
put the number of chars in line i of list into maxchar
end if
end repeat
put maxchar*6 into width
-- This actually makes the field
makefield "Popmenu",width,height,loc
-- Fill the field with the menu options
put list into card field "Popmenu"
-- Here find the the beginning and end of the script for the menu field
-- The menu field has one handler,mouseup,and one function,linechoosen
-- handleraddress returns the line at which a handler or function
-- starts and the line at which it ends
put the script of me into temp
put handleraddress (temp,"mouseup",3,0) into templine
put handleraddress (temp,"linechoosenfixed",item 2 of templine,1) into temp1
put item 1 of templine into tempstart
put item 2 of temp1 into lastone
put tempstart - 1 into templine1
repeat with x=tempstart to lastone
put line x of temp into line (x-templine1) of temp1
end repeat
set the script of card field "Popmenu" to temp1
end popHCmenu
on makefield fieldname,xsize,ysize,dest
-- Input field name,width,height,location
-- This is a general handler which will make a field with the
-- default characteristics
--if the userlevel is not 5 then <========== To insure menu options available
-- put the userlevel into temp1 <========== To insure menu options available
-- set the userlevel to 5 <========== To insure menu options available
-- else <========== To insure menu options available
-- put empty into temp1 <========== To insure menu options available
-- end if <========== To insure menu options available
domenu "new field"
--if temp1 is not empty then <========== To insure menu options available
-- set the userlevel to temp1 <========== To insure menu options available
--end if <========== To insure menu options available
set the width of card field "" to xsize
set the height of card field "" to ysize
set loc of card field "" to dest
set the textfont of card field "" to "new york"
set the textsize of card field "" to 9
set the textstyle of card field "" to "condense"
set the textheight of card field "" to 9
set the style of card field "" to "shadow"
set the textalign of card field "" to "center"
put the id of card field "" into fid
set the locktext of card field "" to true
set name of card field "" to fieldname
set the locktext of card field fieldname to true
choose browse tool
end makefield
function listtoline list
-- input a list "c,x,y,35,100,d"
-- output a variable with item 1 in line 1...item n in line n
repeat with x=1 to the number of items in list
put item x of list into line x of temp
end repeat
return temp
end listtoline
Listing 2
WARNING: The comments we've made about problems with SuperCard™ should be taken with a grain of salt. we've only been using it a few days and the only documentation we have is the manuals that come with it which are not a full blown course for SuperTalk™. The scripts shown below do work but there might be other,better,ways to get the same effect.
on mouseup
--this script is placed in the menu field to handle the user's selection
-- the name of the chosen item is returned(to avoid the handler in
-- the original field (itempicked) from having to know what the
-- possible choices were). The cmdflag(which notes whether you're
-- working with menu choices,instance variable setting,or firing
-- handlers) is also returned.
-- The name of the original field is contained in the second to
-- last line in the menu,while the cmdflag value is contained in the
-- last line. Both of which are kept invisible by the selected
-- sizing for the menu field
put the clickloc into loc
put linechoosenfixed (loc) into itemchosen
put line itemchosen of me into itemchosen
put last line of me into cmdflag
put number of lines in me -1 into temp
put line temp of me into dest
-- These next two lines had to be changed to be compatible with SuperCard™
put itemchosen & "," & cmdflag into tempstring <============
send "itempicked" && tempstring to dest <============
-- now that we're done with it let's delete the menu field
-- In HyperCard™ we used doMenu "cut field" in SuperCard™ you have to use
-- doMenu "cut"
select me
domenu "cut" <============
choose browse tool
end mouseup
on popHCmenu list,loc,cmdflag
--input list of menu options,location of menu,command flag
-- This handler sets up the menu
--first convert the list into a variable with each item in 1 line
--Note we also changed some of the text sizes in the SuperCard™ version
put listtoline(list) into list
put the number of lines in list into temp
--compute the height and width of the field
put (temp*10)+3 into height
put the target into line temp+1 of list
put cmdflag into line temp+2 of list
put 0 into maxchar
repeat with i=1 to temp
if the number of chars in line i of list > maxchar then
put the number of chars in line i of list into maxchar
end if
end repeat
put maxchar*8 into width
-- This actually makes the field
makefield "Popmenu",width,height,loc
-- Fill the field with the menu options
put "Popmenu" into fieldname
put list into card field fieldname
-- In SuperCard™ setting these parameters before entering the text didn't seem to
-- work so we moved them here.
set the textfont of card field fieldname to "monaco"
set the textsize of card field fieldname to 9
set the textstyle of card field fieldname to "condense"
set the textheight of card field fieldname to 10
set the style of card field fieldname to "shadow"
set the textalign of card field fieldname to "center"
-- Here find the the begining and end of the script for the menu field
-- The menu field has one handler,mouseup,and one function,linechoosen
-- handleraddress returns the line at which a handler or function
-- starts and the line at which it ends
put the script of me into temp
put handleraddress (temp,"mouseup",3,0) into templine
put handleraddress (temp,"linechoosenfixed",item 2 of templine,1) into temp1
put item 1 of templine into tempstart
put item 2 of temp1 into lastone
put tempstart - 1 into templine1
repeat with x=tempstart to lastone
put line x of temp into line (x-templine1) of temp1
end repeat
set the script of card field "Popmenu" to temp1
end popHCmenu
on makefield fieldname,xsize,ysize,dest
-- Input field name,width,height,location
-- This is a general handler which will make a field with the
-- default characteristics
-- In HyperCard™ we used doMenu "new field" but SuperCard™ doesn't have
-- such a menu command. In SuperCard™ you can create a new field in a script
-- by using the field rectangle tool
choose field rectangle tool
put dest into start
put item 1 of dest + xsize into item 1 of finish
put item 2 of dest + ysize into item 2 of finish
drag from start to finish
-- It seems that you have to go back to the browse tool in SuperCard™ before
-- using the field
choose browse tool
-- Unlike HyperCard™ SuperCard™ doesn't seem to be able to address fields
-- with no nameby using the name "". But you know that the field you've just
-- made will always have the highest field number
set name of card field (the number of card fields) to fieldname